/**
 * @param {string} s
 * @return {string}
 */
/*
外层的解码需要等待内层解码的结果 因此 先扫描的字符还用不上 需要先存储起来
然后由内到往外 一层一层的解决 因为对于数字的存储 需要用到栈
入栈的时机：
当遇到[, 已经扫描的数字就是’倍数‘的身份 入栈暂存
当遇到[, 已经扫描的字母也要入栈等待 括号里的解码完了 一起参与构建字符串
出栈的时机：
遇到] 内层的扫描完了 栈顶的元素就可以出栈了 共同参与子串的构建
栈顶就是最近遇到的“倍数” 和字母
* */
var decodeString = function(s) {
    //存倍数的栈
    let numstack = []
    // 存字符串的栈
    let strstack = []
    let num = 0
    //最终返回的是字符串 所以利用子串的特性
    let result = ''
    // 遍历逐字进行扫描
    for (const char of s) {
        // 遇到数字
        if (!isNaN(char))  {
            // 算出倍数
            num = num * 10 + Number(char)
        }else if (char == '[') {
            strstack.push(result)
            result = '' // 字符串清零
            numstack.push(num)
            num = 0   // 倍数清零
        }else if (char == ']')  {
            let repeatTimes = numstack.pop()     // 复制得次数
            result = strstack.pop() + result.repeat(repeatTimes)    // 构建子串
        }else {
            result +=char    // 遇到字母追加给result
        }
    }
    return result
}
let s = "3[a]2[bc]"
console.log(decodeString(s))